package com.github.skystardust.lotteryex.gui;

import com.github.skystardust.lotteryex.gui.animation.AbstractAnimation;
import com.github.skystardust.lotteryex.gui.inventory.LotteryInventory;
import com.github.skystardust.lotteryex.utils.OptionalUtils;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import org.bukkit.configuration.serialization.ConfigurationSerializable;

import javax.annotation.Nonnull;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

@EqualsAndHashCode(of = "uuid")
@ToString
public class LotteryAnimation implements ConfigurationSerializable {
    private UUID uuid;
    private LotteryInventory currentLotteryInventory;
    private AbstractAnimation lotteryAnimation;

    public LotteryAnimation(UUID uuid, LotteryInventory currentLotteryInventory, AbstractAnimation lotteryAnimation) {
        this.uuid = uuid;
        this.currentLotteryInventory = currentLotteryInventory;
        this.lotteryAnimation = lotteryAnimation;
    }

    public LotteryAnimation(UUID uuid, LotteryInventory currentLotteryInventory) {
        this.uuid = uuid;
        this.currentLotteryInventory = currentLotteryInventory;
    }

    public LotteryAnimation(Map<String, Object> stringObjectMap) {
        this.uuid = UUID.fromString(((String) stringObjectMap.get("uuid")));
        /**
         * todo 增强健壮性,修改所有serialize方法为OptionalUtils实现
         * todo AbstractAnimation所有子类实现序列化
         * todo AbstractAnimationRunnable所有子类实现序列化,主要是为了抽奖动画所展示的奖品可以和实际奖品不想同,提高可自定义性
         *
         */
        this.uuid = UUID.fromString((String) stringObjectMap.get("uuid"));
        this.currentLotteryInventory = (LotteryInventory) stringObjectMap.get("currentLotteryInventory");
        this.lotteryAnimation = (AbstractAnimation) stringObjectMap.get("lotteryAnimation");
    }

    private LotteryAnimation(Builder builder) {
        setUuid(builder.lotteryInventoryOwner);
        setCurrentLotteryInventory(builder.currentLotteryInventory);
        setLotteryAnimation(builder.lotteryAnimation);
    }

    public static Builder newBuilder() {
        return new Builder();
    }

    public UUID getUuid() {
        return uuid;
    }

    public void setUuid(UUID uuid) {
        this.uuid = uuid;
    }

    public LotteryInventory getCurrentLotteryInventory() {
        return currentLotteryInventory;
    }

    public void setCurrentLotteryInventory(LotteryInventory currentLotteryInventory) {
        this.currentLotteryInventory = currentLotteryInventory;
    }

    public AbstractAnimation getLotteryAnimation() {
        return lotteryAnimation;
    }

    public void setLotteryAnimation(AbstractAnimation lotteryAnimation) {
        this.lotteryAnimation = lotteryAnimation;
    }

    @Override
    public Map<String, Object> serialize() {
        return new OptionalUtils<>(() -> {
            HashMap<String, Object> stringObjectHashMap = new HashMap<>();
            stringObjectHashMap.put("uuid", uuid.toString());
            stringObjectHashMap.put("currentLotteryInventory", currentLotteryInventory);
            stringObjectHashMap.put("lotteryAnimation", lotteryAnimation);
            return stringObjectHashMap;
        }).getOptional().orElseGet(HashMap::new);
    }

    public static final class Builder {
        private UUID lotteryInventoryOwner;
        private LotteryInventory currentLotteryInventory;
        private AbstractAnimation lotteryAnimation;

        private Builder() {
        }

        @Nonnull
        public Builder withLotteryInventoryOwner(@Nonnull UUID val) {
            lotteryInventoryOwner = val;
            return this;
        }

        @Nonnull
        public Builder withCurrentLotteryInventory(@Nonnull LotteryInventory val) {
            currentLotteryInventory = val;
            return this;
        }

        @Nonnull
        public Builder withLotteryAnimation(@Nonnull AbstractAnimation val) {
            lotteryAnimation = val;
            return this;
        }

        @Nonnull
        public LotteryAnimation build() {
            return new LotteryAnimation(this);
        }
    }
}
